using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Net;
using System.Runtime.Serialization.Formatters.Binary;
using Sanelib.Core;

namespace Sanelib.Common.Extensions
{
    public class ImageUtility
    {
        public const string NoImageData = "";
        public static string ImageToBase64(Image image, ImageFormat format)
        {
            using (var ms = new MemoryStream())
            {
                image.Save(ms, format);
                var imageBytes = ms.ToArray();
                return BytesToBase64(imageBytes);
            }
        }

        public static string BytesToBase64(byte[] imageBytes)
        {
            if (imageBytes == null || imageBytes.Length == 0) return "";
            var base64String = Convert.ToBase64String(imageBytes);
            return base64String;
        }

        public static byte[] Base64ToBytes(string base64)
        {
            if (base64.Length == 0) return null;
            var imageBytes = Convert.FromBase64String(base64);
            return imageBytes;
        }

        public static byte[] BmpToBytes(Bitmap bmp)
        {
            // stream to save the bitmap to
            var ms = new MemoryStream();
            var bf = new BinaryFormatter();
            bf.Serialize(ms, bmp);

            // read to end
            var bmpBytes = ms.GetBuffer();
            bmp.Dispose();
            ms.Close();

            return bmpBytes;
        }

        public static Bitmap BytesToBmp(byte[] bmpBytes)
        {
            var bf = new BinaryFormatter();
            // copy the bytes to the memory
            var ms = new MemoryStream(bmpBytes);
            return (Bitmap)bf.Deserialize(ms);
        }

        public static byte[] DownloadImage(string imageUrl)
        {
            byte[] bytes;

            try
            {
                // Open a connection
                var webRequest = (HttpWebRequest)WebRequest.Create(imageUrl);

                webRequest.AllowWriteStreamBuffering = true;

                // You can also specify additional header values like the user agent or the referer: (Optional)
                webRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)";
                webRequest.Referer = "http://www.google.com/";
                webRequest.Timeout = 20000;

                using (var response = webRequest.GetResponse())
                {
                    var stm = response.GetResponseStream();
                    if (stm == null) throw new Exception("Response is null");
                    using (var reader = new BinaryReader(stm))
                    {
                        bytes = reader.ReadBytes(1 * 1024 * 1024 * 10);
                    }
                }
            }
            catch (Exception exception)
            {
                Logger.Log(LogType.Error, typeof(ImageUtility), "DownloadImage", exception);
                return null;
            }
            return bytes;
        }

        public static byte[] OptimizeWebImage(byte[] srcBytes, int height, int width)
        {
            if (srcBytes == null || srcBytes.Length == 0) return null;

            var img = Image.FromStream(new MemoryStream(srcBytes));

            var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            using (var gr = Graphics.FromImage(bmp))
            {
                gr.DrawImage(img, new Rectangle(0, 0, 100, 100));
            }

            var ms = new MemoryStream();
            bmp.Save(ms, ImageFormat.Jpeg);

            bmp.Dispose();
            ms.Close();
            img.Dispose();

            return ms.GetBuffer();
        }
    }
}